<template>
  <div class="card">
    <div class="page-head">
      <div class="page-title">用户管理</div>
      <div class="page-subtitle">管理平台用户与基础信息，支持查询、新增、修改、删除</div>
    </div>

    <!-- 搜索筛选区域 -->
    <div class="search-section">
      <div class="search-row">
        <div class="search-item">
          <label class="search-label">用户名</label>
          <input 
            type="text" 
            v-model="searchForm.account" 
            placeholder="请输入用户名" 
            class="search-input"
          />
        </div>
        <div class="search-item">
          <label class="search-label">昵称</label>
          <input 
            type="text" 
            v-model="searchForm.name" 
            placeholder="请输入昵称" 
            class="search-input"
          />
        </div>
      </div>
      
      <div class="search-row">
        <div class="search-item">
          <label class="search-label">手机号码</label>
          <input 
            type="text" 
            v-model="searchForm.phone" 
            placeholder="请输入手机号码" 
            class="search-input"
          />
        </div>
        <div class="search-item">
          <label class="search-label">状态</label>
          <select v-model="searchForm.status" class="search-select">
            <option value="">用户状态</option>
            <option value="0">正常</option>
            <option value="1">禁用</option>
          </select>
        </div>
      </div>

      <div class="search-row">
        <div class="search-item">
          <label class="search-label">创建时间</label>
              <div class="date-range">
                <input 
                  type="date" 
                  v-model="searchForm.startDate" 
                  class="date-input"
                />
                <span class="date-separator">-</span>
                <input 
                  type="date" 
                  v-model="searchForm.endDate" 
                  class="date-input"
                />
              </div>
        </div>
        <div class="search-item">
          <button class="search-btn" @click="handleSearch">搜索</button>
          <button class="reset-btn" @click="handleReset">重置</button>
        </div>
      </div>
    </div>

    <!-- 操作按钮区域 -->
    <div class="action-section">
      <button class="action-btn add-btn" @click="handleAdd">+ 新增</button>
      <button class="action-btn edit-btn" @click="handleEdit">修改</button>
      <button class="action-btn delete-btn" @click="handleDelete">删除</button>
      <button class="action-btn refresh-btn" @click="refreshData">刷新</button>
    </div>

    <!-- 数据表格 -->
    <div class="table-section">
      <table class="data-table">
        <thead>
          <tr>
            <th class="checkbox-col">
              <input type="checkbox" v-model="selectAll" @change="toggleSelectAll" />
            </th>
            <th>ID</th>
            <th>用户名</th>
            <th>昵称</th>
            <th>邮箱</th>
            <th>手机号</th>
            <th>性别</th>
            <th>状态</th>
            <th>创建时间</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="user in tableData" :key="user.id" 
              :class="{ selected: selectedUsers.includes(user.id) }"
              @click="toggleSelect(user.id)">
            <td class="checkbox-col">
              <input type="checkbox" :checked="selectedUsers.includes(user.id)" @click.stop />
            </td>
            <td>{{ user.id }}</td>
            <td>{{ user.username }}</td>
            <td>{{ user.nickname }}</td>
            <td>{{ user.email }}</td>
                <td>{{ user.phone || '-' }}</td>
                <td>{{ user.gender || '-' }}</td>
                <td>
              <span class="status-badge" :class="user.status === '正常' ? 'status-normal' : 'status-disabled'">
                {{ user.status }}
              </span>
            </td>
            <td>{{ user.create_time }}</td>
          </tr>
          <tr v-if="tableData.length === 0">
            <td colspan="9" class="empty-data">暂无数据</td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 分页控件 -->
    <div class="pagination-section">
      <div class="pagination-info">共 {{ total }} 条</div>
      <div class="pagination-controls">
        <button class="page-btn" @click="goToFirstPage" :disabled="pageNum === 1">首页</button>
        <button class="page-btn" @click="onPageChange(pageNum - 1)" :disabled="pageNum === 1">上一页</button>
        <span class="page-info">第 {{ pageNum }} / {{ totalPages }} 页</span>
        <button class="page-btn" @click="onPageChange(pageNum + 1)" :disabled="pageNum === totalPages">下一页</button>
        <button class="page-btn" @click="goToLastPage" :disabled="pageNum === totalPages">末页</button>
      </div>
    </div>

    <!-- 新增/编辑对话框 -->
    <div v-if="showDialog" class="dialog-overlay" @click="closeDialog">
      <div class="dialog-content" @click.stop>
        <div class="dialog-header">
          <h3>{{ isEdit ? '编辑用户' : '新增用户' }}</h3>
          <button class="close-btn" @click="closeDialog">×</button>
        </div>
        <div class="dialog-body">
          <div class="form-item">
            <label>用户名：</label>
            <input v-model="dialogForm.username" placeholder="请输入用户名" />
          </div>
          <div class="form-item">
            <label>昵称：</label>
            <input v-model="dialogForm.nickname" placeholder="请输入昵称" />
          </div>
          <div class="form-item">
            <label>邮箱：</label>
            <input v-model="dialogForm.email" type="email" placeholder="请输入邮箱" />
          </div>
          <div class="form-item">
            <label>手机号：</label>
            <input v-model="dialogForm.phone" placeholder="请输入手机号" />
          </div>
          <div class="form-item">
            <label>性别：</label>
            <select v-model="dialogForm.gender">
              <option value="">请选择</option>
              <option value="男">男</option>
              <option value="女">女</option>
            </select>
          </div>
          <div class="form-item">
            <label>状态：</label>
            <select v-model="dialogForm.status">
              <option value="正常">正常</option>
              <option value="禁用">禁用</option>
            </select>
          </div>
          <div class="form-item" v-if="!isEdit">
            <label>密码：</label>
            <input v-model="dialogForm.password" type="password" placeholder="请输入密码" />
          </div>
        </div>
        <div class="dialog-footer">
          <div class="dialog-actions">
            <button v-if="isEdit" class="change-password-btn" @click="handleChangePassword">修改密码</button>
            <div class="dialog-buttons">
              <button class="cancel-btn" @click="closeDialog">取消</button>
              <button class="confirm-btn" @click="handleConfirm">确认</button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 修改密码对话框 -->
    <div v-if="showChangePasswordDialog" class="dialog-overlay" @click="closeChangePasswordDialog">
      <div class="dialog-content" @click.stop>
        <div class="dialog-header">
          <h3>修改密码</h3>
          <button class="close-btn" @click="closeChangePasswordDialog">×</button>
        </div>
        <div class="dialog-body">
          <div class="form-item">
            <label>新密码：</label>
            <input v-model="changePasswordForm.newPassword" type="password" placeholder="请输入新密码" />
          </div>
          <div class="form-item">
            <label>确认密码：</label>
            <input v-model="changePasswordForm.confirmPassword" type="password" placeholder="请再次输入新密码" />
          </div>
        </div>
        <div class="dialog-footer">
          <div class="dialog-buttons">
            <button class="cancel-btn" @click="closeChangePasswordDialog">取消</button>
            <button class="confirm-btn" @click="handleConfirmChangePassword">确认</button>
          </div>
        </div>
      </div>
    </div>

    <!-- 提示框 -->
    <div v-if="showToast" class="custom-toast">{{ toastMsg }}</div>
  </div>
</template>

<script setup>
defineOptions({ name: 'AdminUsers' });
import { ref, computed, onMounted } from 'vue';
import axios from 'axios';
import { API_ENDPOINTS, PAGING_PARAM_MAP } from '@/api/config';

const tableData = ref([]);
const pageNum = ref(1);
const pageSize = ref(10);
const total = ref(0);
const searchForm = ref({
  account: '',
  name: '',
  phone: '',
  status: '',
  startDate: '',
  endDate: ''
});
const selectedUsers = ref([]);
const selectAll = ref(false);
const showDialog = ref(false);
const isEdit = ref(false);
const dialogForm = ref({
  id: null,
  username: '',
  nickname: '',
  email: '',
  phone: '',
  gender: '',
  status: '正常',
  password: ''
});
const changePasswordForm = ref({
  newPassword: '',
  confirmPassword: ''
});

const toastMsg = ref('');
const showToast = ref(false);
const showChangePasswordDialog = ref(false);

const showToastMsg = (msg) => {
  toastMsg.value = msg;
  showToast.value = true;
  setTimeout(() => {
    showToast.value = false;
  }, 2000);
};

const totalPages = computed(() => Math.ceil(total.value / pageSize.value));

async function fetchUsers() {
  try {
    const params = {
      [PAGING_PARAM_MAP.pageNum]: pageNum.value,
      [PAGING_PARAM_MAP.pageSize]: pageSize.value
    };
    
    // 如果有搜索条件，添加到参数中
    if (searchForm.value.account) params.username = searchForm.value.account;
    if (searchForm.value.name) params.nickname = searchForm.value.name;
    if (searchForm.value.phone) params.phone = searchForm.value.phone;
    if (searchForm.value.status !== '') params.status = searchForm.value.status;
    if (searchForm.value.startDate) params.startDate = searchForm.value.startDate;
    if (searchForm.value.endDate) params.endDate = searchForm.value.endDate;
    
    const resp = await axios.get(API_ENDPOINTS.USER_LIST_ENDPOINT, { params });

    const body = resp.data || {};
    const ok = body.success === true || body.code === 200 || Array.isArray(body);
    if (!ok) throw new Error('响应不包含成功标记');

    // 兼容多种后端包装
    const container = Array.isArray(body)
      ? null
      : (body.data || null);
    
    const list = Array.isArray(container)
      ? container
      : (container?.records || container?.list || []);
      
    total.value = (container?.total) || list.length;
    tableData.value = list.map(u => ({
      id: u.id,
      username: u.username || '-',
      nickname: u.nickname || '-',
      email: u.email || '-',
      phone: u.phone || '-',
      gender: (u.gender === 1 ? '男' : u.gender === 2 ? '女' : '未知'),
      status: (u.status === 0 || u.status === '0' ? '正常' : '禁用'),
      create_time: u.createTime || u.create_time || '-'
    }));
  } catch (e) {
    tableData.value = [];
    total.value = 0;
    showToastMsg('加载用户列表失败');
  }
}

function onPageChange(page) {
  if (page < 1 || page > totalPages.value) return;
  pageNum.value = page;
  fetchUsers();
}

function goToFirstPage() {
  if (pageNum.value > 1) onPageChange(1);
}

function goToLastPage() {
  if (pageNum.value < totalPages.value) onPageChange(totalPages.value);
}

function handleSearch() {
  pageNum.value = 1;
  fetchUsers();
}

function handleReset() {
  searchForm.value = {
    account: '',
    name: '',
    phone: '',
    status: '',
    startDate: '',
    endDate: ''
  };
  pageNum.value = 1;
  fetchUsers();
}

function refreshData() {
  fetchUsers();
  showToastMsg('刷新成功');
}

function toggleSelect(userId) {
  const index = selectedUsers.value.indexOf(userId);
  if (index > -1) {
    selectedUsers.value.splice(index, 1);
  } else {
    selectedUsers.value.push(userId);
  }
}

function toggleSelectAll() {
  if (selectAll.value) {
    selectedUsers.value = tableData.value.map(u => u.id);
  } else {
    selectedUsers.value = [];
  }
}

async function handleAdd() {
  isEdit.value = false;
  dialogForm.value = {
    id: null,
    username: '',
    nickname: '',
    email: '',
    phone: '',
    gender: '',
    status: '正常',
    password: ''
  };
  showDialog.value = true;
}

async function handleEdit() {
  if (selectedUsers.value.length === 0) {
    showToastMsg('请先选择要修改的用户');
    return;
  }
  if (selectedUsers.value.length > 1) {
    showToastMsg('一次只能修改一个用户');
    return;
  }
  
  try {
    const userId = selectedUsers.value[0];
    const resp = await axios.get(`http://localhost:8086/user/${userId}`);
    
    if (resp.data.success) {
      let user = resp.data.data?.user || resp.data.data || null;
      
      if (!user || !user.id) {
        showToastMsg('获取用户信息失败：用户ID为空');
        return;
      }
      
      isEdit.value = true;
      dialogForm.value = {
        id: parseInt(user.id),
        username: user.username || '',
        nickname: user.nickname || '',
        email: user.email || '',
        phone: user.phone || '',
        gender: (user.gender === 1 ? '男' : user.gender === 2 ? '女' : ''),
        status: (user.status === 0 ? '正常' : '禁用'),
        password: ''
      };
      
      showDialog.value = true;
    } else {
      showToastMsg('获取用户信息失败');
    }
  } catch (e) {
    showToastMsg('获取用户信息失败');
  }
}

async function handleDelete() {
  if (selectedUsers.value.length === 0) {
    showToastMsg('请先选择要删除的用户');
    return;
  }
  
  if (!confirm(`确定要删除选中的 ${selectedUsers.value.length} 个用户吗？`)) {
    return;
  }
  
  try {
    const deletePromises = selectedUsers.value.map(id => 
      axios.delete(`http://localhost:8086/user/${id}`)
    );
    await Promise.all(deletePromises);
    showToastMsg('删除成功');
    selectedUsers.value = [];
    fetchUsers();
  } catch (e) {
    showToastMsg('删除失败');
  }
}

async function handleConfirm() {
  try {
    if (isEdit.value) {
      const genderValue = dialogForm.value.gender === '男' ? 1 : (dialogForm.value.gender === '女' ? 2 : 0);
      const statusValue = dialogForm.value.status === '正常' ? 0 : 1;
      
      const requestData = {
        id: parseInt(dialogForm.value.id),
        username: dialogForm.value.username,
        nickname: dialogForm.value.nickname,
        email: dialogForm.value.email,
        phone: dialogForm.value.phone,
        gender: genderValue,
        status: statusValue
      };
      
      const response = await axios.put('http://localhost:8086/user/update', requestData);
      
      if (response.data.success) {
        showToastMsg('修改成功');
      } else {
        showToastMsg('修改失败：' + (response.data.message || '未知错误'));
        return;
      }
    } else {
      if (!dialogForm.value.password || dialogForm.value.password.trim() === '') {
        showToastMsg('请输入密码');
        return;
      }
      
      const genderValue = dialogForm.value.gender === '男' ? 1 : (dialogForm.value.gender === '女' ? 2 : 0);
      const statusValue = dialogForm.value.status === '正常' ? 0 : 1;
      
      const response = await axios.post('http://localhost:8086/user/add', {
        username: dialogForm.value.username,
        nickname: dialogForm.value.nickname,
        email: dialogForm.value.email,
        phone: dialogForm.value.phone,
        password: dialogForm.value.password,
        gender: genderValue,
        status: statusValue
      });
      
      if (response.data.success) {
        showToastMsg('新增成功');
      } else {
        showToastMsg('新增失败：' + (response.data.message || '未知错误'));
        return;
      }
    }
    closeDialog();
    fetchUsers();
  } catch (e) {
    showToastMsg('操作失败：' + (e.response?.data?.message || e.message));
  }
}

function closeDialog() {
  showDialog.value = false;
}

function handleChangePassword() {
  changePasswordForm.value = {
    newPassword: '',
    confirmPassword: ''
  };
  showChangePasswordDialog.value = true;
}

function closeChangePasswordDialog() {
  showChangePasswordDialog.value = false;
  changePasswordForm.value = {
    newPassword: '',
    confirmPassword: ''
  };
}

async function handleConfirmChangePassword() {
  if (!changePasswordForm.value.newPassword || changePasswordForm.value.newPassword.trim() === '') {
    showToastMsg('请输入新密码');
    return;
  }
  
  if (changePasswordForm.value.newPassword !== changePasswordForm.value.confirmPassword) {
    showToastMsg('两次输入的密码不一致');
    return;
  }
  
  if (changePasswordForm.value.newPassword.length < 6) {
    showToastMsg('密码长度不能少于6位');
    return;
  }
  
  try {
    const response = await axios.post('http://localhost:8086/user/changePassword', {
      id: dialogForm.value.id,
      newPassword: changePasswordForm.value.newPassword
    });
    
    if (response.data.success) {
      showToastMsg('密码修改成功');
      closeChangePasswordDialog();
    } else {
      showToastMsg('密码修改失败：' + (response.data.message || '未知错误'));
    }
  } catch (e) {
    showToastMsg('修改密码失败：' + (e.response?.data?.message || e.message));
  }
}

onMounted(fetchUsers);
</script>

<style scoped>
.card { 
  background: #fff; 
  border-radius: 8px; 
  padding: 24px; 
  box-shadow: 0 1px 3px rgba(0,0,0,.08); 
}

.page-head {
  margin-bottom: 20px;
}

.page-title {
  font-size: 24px;
  font-weight: bold;
  color: #23272b;
  margin-bottom: 8px;
}

.page-subtitle {
  font-size: 14px;
  color: #666;
}

.search-section {
  background: #f5f5f5;
  border-radius: 6px;
  padding: 16px;
  margin-bottom: 16px;
}

.search-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 20px;
}

.search-row:last-of-type {
  grid-template-columns: 1.5fr 1fr;
  margin-bottom: 0;
}

.search-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.search-label {
  min-width: 70px;
  text-align: right;
  font-size: 15px;
  font-weight: bold;
  color: #23272b;
  flex-shrink: 0;
}

.search-input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 14px;
  background: #fff;
  outline: none;
  transition: border 0.2s;
}

.search-input:focus {
  border: 1.5px solid #23272b;
}

.search-select {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 14px;
  background: #fff;
  outline: none;
  cursor: pointer;
  transition: border 0.2s;
}

.search-select:focus {
  border: 1.5px solid #23272b;
}

.date-range {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
}

.date-input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 14px;
  background: #fff;
  outline: none;
  transition: border 0.2s;
}

.date-input:focus {
  border: 1.5px solid #23272b;
}

.date-separator {
  color: #666;
  font-size: 16px;
}

.search-btn {
  padding: 10px 24px;
  background: linear-gradient(180deg, #23272b 0%, #43484d 100%);
  color: #fff;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  transition: filter 0.2s;
}

.search-btn:hover {
  filter: brightness(1.1);
}

.reset-btn {
  padding: 10px 24px;
  background: #fff;
  color: #23272b;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  transition: background 0.2s;
}

.reset-btn:hover {
  background: #f5f5f5;
}

.action-section {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.action-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  transition: filter 0.2s, transform 0.2s;
}

.action-btn:hover {
  filter: brightness(1.1);
  transform: translateY(-1px);
}

.add-btn { background: #e3f2fd; color: #1976d2; }
.edit-btn { background: #e8f5e9; color: #388e3c; }
.delete-btn { background: #ffebee; color: #d32f2f; }
.refresh-btn { background: #fff3e0; color: #f57c00; }

.table-section {
  overflow-x: auto;
  margin-bottom: 20px;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
}

.data-table thead {
  background: #f5f5f5;
}

.data-table th {
  padding: 12px;
  text-align: left;
  font-weight: bold;
  font-size: 14px;
  color: #23272b;
  border-bottom: 2px solid #ddd;
}

.data-table td {
  padding: 12px;
  font-size: 14px;
  color: #333;
  border-bottom: 1px solid #eee;
}

.data-table tbody tr {
  cursor: pointer;
  transition: background 0.2s;
}

.data-table tbody tr:hover {
  background: #f9f9f9;
}

.data-table tbody tr.selected {
  background: #e3f2fd;
}

.checkbox-col {
  width: 40px;
  text-align: center;
}

.data-table input[type="checkbox"] {
  cursor: pointer;
}

.status-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: bold;
}

.status-normal {
  background-color: #e3f2fd;
  color: #1976d2;
}

.status-disabled {
  background-color: #ffebee;
  color: #d32f2f;
}

.empty-data {
  text-align: center;
  padding: 40px;
  color: #999;
}

.pagination-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.pagination-info {
  font-size: 14px;
  color: #666;
}

.pagination-controls {
  display: flex;
  align-items: center;
  gap: 12px;
}

.page-btn {
  padding: 8px 16px;
  border: 1px solid #ddd;
  background: #fff;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s;
}

.page-btn:hover:not(:disabled) {
  background: #f5f5f5;
  border-color: #23272b;
}

.page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.page-info {
  font-size: 14px;
  color: #666;
}

.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.dialog-content {
  background: #fff;
  border-radius: 8px;
  width: 90%;
  max-width: 500px;
  max-height: 90vh;
  overflow-y: auto;
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid #eee;
}

.dialog-header h3 {
  margin: 0;
  font-size: 20px;
  font-weight: bold;
  color: #23272b;
}

.close-btn {
  font-size: 24px;
  background: none;
  border: none;
  cursor: pointer;
  color: #999;
  padding: 0;
  width: 30px;
  height: 30px;
  line-height: 30px;
}

.close-btn:hover {
  color: #333;
}

.dialog-body {
  padding: 20px;
}

.form-item {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}

.form-item label {
  min-width: 80px;
  font-size: 14px;
  color: #333;
}

.form-item input,
.form-item select {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 14px;
}

.form-item input:focus,
.form-item select:focus {
  outline: none;
  border-color: #23272b;
}

.dialog-footer {
  padding: 20px;
  border-top: 1px solid #eee;
}

.dialog-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.dialog-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

.change-password-btn {
  padding: 10px 24px;
  background: #fff3e0;
  color: #f57c00;
  border: 1px solid #ffb74d;
  border-radius: 6px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
  transition: background 0.2s;
}

.change-password-btn:hover {
  background: #ffe0b2;
}

.cancel-btn,
.confirm-btn {
  padding: 10px 24px;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  font-weight: bold;
  cursor: pointer;
}

.cancel-btn {
  background: #f5f5f5;
  color: #666;
}

.confirm-btn {
  background: #23272b;
  color: #fff;
}

.confirm-btn:hover {
  background: #43484d;
}

.custom-toast {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0,0,0,0.8);
  color: #fff;
  padding: 16px 32px;
  border-radius: 8px;
  font-size: 16px;
  z-index: 9999;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  pointer-events: none;
  animation: fadeInOut 2s;
}

@keyframes fadeInOut {
  0% { opacity: 0; }
  10% { opacity: 1; }
  90% { opacity: 1; }
  100% { opacity: 0; }
}
</style>
